package com.itheima.wisdomnext.util;

import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

@Component
public class JwtUtil {
    private static final SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS512;

    @Value("${jwt.secret}")
    private String secretKey;

    @Value("${jwt.expiration-days:7}") // 默认7天
    private int expirationDays;

    // 从token中提取用户名
    public String getUsernameFromToken(String token) {
        return getClaimFromToken(token, Claims::getSubject);
    }

    // 从token中提取过期时间
    public Date getExpirationDateFromToken(String token) {
        return getClaimFromToken(token, Claims::getExpiration);
    }

    // 通用claims提取方法
    private <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = getAllClaimsFromToken(token);
        return claimsResolver.apply(claims);
    }

    // 获取所有claims
    private Claims getAllClaimsFromToken(String token) {
        try {
            return Jwts.parser()
                    .setSigningKey(secretKey)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (ExpiredJwtException e) {
            throw new JwtException("Token已过期", e);
        } catch (UnsupportedJwtException | MalformedJwtException e) {
            throw new JwtException("无效的Token格式", e);
        } catch (SignatureException e) {
            throw new JwtException("Token签名验证失败", e);
        } catch (IllegalArgumentException e) {
            throw new JwtException("Token参数异常", e);
        }
    }

    // 检查token是否过期
    public boolean isTokenExpired(String token) {
        final Date expiration = getExpirationDateFromToken(token);
        return expiration.before(new Date());
    }

    // 验证token
    public boolean validateToken(String token, UserDetails userDetails) {
        final String username = getUsernameFromToken(token);
        return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
    }

    // 生成token
    public String generateToken(UserDetails userDetails) {
        return generateToken(userDetails.getUsername());
    }

    // 生成token（重载方法）
    public String generateToken(String username) {
        Date now = new Date();
        Date expirationDate = new Date(now.getTime() + TimeUnit.DAYS.toMillis(expirationDays));

        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(now)
                .setExpiration(expirationDate)
                .signWith(SIGNATURE_ALGORITHM, secretKey)
                .compact();
    }

    // 获取剩余有效时间（毫秒）
    public long getRemainingTime(String token) {
        Date expiration = getExpirationDateFromToken(token);
        return expiration.getTime() - System.currentTimeMillis();
    }
}